﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Zack.ASPNETCore;

namespace WebApplication2.Controllers
{
  [Route("api/[controller]/[action]")]
  [ApiController]
  public class TestController : ControllerBase
  {
    private readonly IMemoryCache memory;

    [HttpGet]
    public Person GetPerson()
    {
      return new Person("yezi", 19);
    }
    [HttpPost]
    public string[] SaveNote(SaveNoteRequest request)
    {
      System.IO.File.WriteAllText($"{request.Title}.txt", request.Content);
      return new string[] { "OK", request.Title };
    }

    [HttpGet]
    public async Task<Person> GetPerson1(int s)
    {
      await Task.Delay(1);
      return new Person("kj", s);
    }
    [HttpGet]
    public IActionResult GetCJ(int id)
    {
      if (id == 0)
      {
        return Ok(33);
      }
      else if (id == 1)
      {

        return Ok(88);
      }
      else
      {
        return NotFound(/*"Id错误"*/ new Person("Not", 0));
      }
    }
    [HttpGet]
    public ActionResult<int> GetCJ2(int id)
    {
      if (id == 0)
      {
        return 33;
      }
      else if (id == 1)
      {

        return 88;
      }
      else
      {
        return NotFound(/*"Id错误"*/ new Person("Not", 0));
      }
    }

    [HttpGet("{i1}/{i2}")]
    public int Mulit(int i1, int i2)
    {
      return i1 + i2;
    }


    /// <summary>
    /// 如果一个service构建很耗时，且其他方法不使用它，可以通过[FromServices]特性，只在这个方法调用时给它注入服务
    /// </summary>
    /// <param name="addService"></param>
    /// <returns></returns>
    [HttpGet]
    public int Add2([FromServices] AddService addService, int a, int b)
    {
      return addService.GetInt();
    }
    /// <summary>
    /// 告诉客户端可以缓存30秒 
    /// </summary>
    /// <returns></returns>
    [ResponseCache(Duration = 30)]
    [HttpGet]
    public DateTime GetDateTime()
    {
      return DateTime.Now;
    }

    public TestController(IMemoryCache memory, IMemoryCacheHelper memoryHelper)
    {
      this.memory = memory;
      this.memoryHelper = memoryHelper;
    }
    [HttpGet]
    public async Task<ActionResult<Person?>> GetById(int id)
    {
      //内存缓存 1、从缓存取数据 2、从数据库取数据 返回调用并保存到缓存中
      var a = await memory.GetOrCreateAsync("Person" + id, async (e) =>
       {
         await Task.Delay(id);

         //两种缓存过期时间可以混用。但绝对时间应大于延迟时间

         //通过ICacheEntry 设置缓存的绝对时间，超过时间缓存失效
         //通过Random.Shared.Next() 随机一下过期时间，避免缓存雪崩
         e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Random.Shared.NextDouble(2,15)+ 20);
         //滑动时间 超时时间内访问的话会延迟时间
         e.SlidingExpiration = TimeSpan.FromSeconds(10);
         return id + 1;
       });
      return NotFound(id);
    }


    private readonly IMemoryCacheHelper memoryHelper;
    /// <summary>
    /// 通过IMemoryCacheHelper 更方便的使用内存缓存和设置缓存时间
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<ActionResult<string>> TestIMemoryCacheHelper(int id)
    {
    
      var b =await memoryHelper.GetOrCreateAsync($"Book{id}", async (e) =>
      {
        await Task.Delay(1);
        return (id + 1).ToString();
      },30);
      if (b==null)
      {
        return NotFound(id);
      }
      //return Ok(b);
      return b;
    }
  }
}
